/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "ath_lb.h"


/* shm object ptr: there is only one per proc, so its global to shmemory */
static apr_shm_t *_ath_shm_seg = NULL;

int
ath_shm_available()
{
    if (_ath_shm_seg)
	return 1;
    return 0;
}

/* wraps apr_shm_create to trap desired errors */
int 
ath_shm_create(apr_pool_t *pool, const char *path)
{
    int result;
    ASSERT(path);
    ASSERT(pool);

    /* clean up in case of previous unclean shutdown */
    apr_shm_remove(path, pool);

    result = apr_shm_create(&_ath_shm_seg, ATH_SHM_SIZE, path, pool);  
    return result;
}

/* attach to already created shm segment */
int 
ath_shm_attach(apr_pool_t *pool, const char *path)
{
    int result;
    ASSERT(path);
    ASSERT(pool);

    result = apr_shm_attach(&_ath_shm_seg, path, pool);
    return result;
}

/* attach to already created shm segment */
int 
ath_shm_destroy()
{
    int result = APR_SUCCESS;
    if (_ath_shm_seg)
	apr_shm_destroy(_ath_shm_seg);
    return result;
}

/* returns ptr to useable shared memory area */
ath_shm_blob * 
ath_shm_blob_get()
{
    ASSERT(_ath_shm_seg);
    ath_shm_blob *shmob = (ath_shm_blob *) apr_shm_baseaddr_get(_ath_shm_seg);
    return shmob;
}

/* returns ptr to farm array in shm */
ath_farm * 
ath_shm_farmbase()
{
    ath_shm_blob *shmob = ath_shm_blob_get();
    ASSERT(shmob->farm);
    return shmob->farm;
}

/* returns ptr to phys array in shm */
ath_phys * 
ath_shm_physbase()
{
    ath_shm_blob *shmob = ath_shm_blob_get();
    ASSERT(shmob->phys);
    return shmob->phys;
}

/* returns ptr to engine array (of 1) in shm */
ath_engine * 
ath_shm_enginebase()
{
    ath_shm_blob *shmob = ath_shm_blob_get();
    ASSERT(shmob->engine);
    return shmob->engine;
}

/* initializes entire shared memory segment to expected values
 * conveniently purifies it on httpd restart
 */
void 
ath_shm_blob_format()
{
    int i,j;
    ath_farm *farm;
    ath_phys *phys;
    ath_engine *engine = ath_engine_get();
  
    /* format farm section */
    for (i = 0; i < ATH_FARM_HARDMAX; i++)
      {
	  farm = ath_farm_raw_for_idx(i);
	  ath_farm_format(farm);
	  farm->idx = i;
      }
    /* no need to format farm's algo_def since engine will with configure */

    /* format phys array */
    for (i = 0; i < ATH_PHYS_HARDMAX; i++)
      {
	  phys = ath_phys_raw_for_idx(i);
	  ath_phys_format(phys);
	  phys->idx = i;
      }

    /* format engine */
    ath_engine_format(engine);
}

#include "ath.h"

/* util for copying strings into shared memory */
char * 
ath_shm_strncpy(char *dst, const char *src, int limit)
{
    int i = 0;
    ASSERT(dst);
    ASSERT(limit > -1);

    /* allow copying of nulls and zero lengths */
    if ((src == NULL) || (i = 0))
	dst = NULL;
    else 
      {
	  while ((*(src + i) != (int) NULL) && (i < limit))
	    {
		*(dst + i) = *(src + i);
		i++;
	    }
	  *(dst + i) = (int) NULL; /* terminate the destination */
      }
    return dst;
}
